package com.thirdguardian.sign.signv1;

import com.thirdguardian.sign.comm.CommUtils;
import com.thirdguardian.sign.comm.ConstStr;

import java.util.Map;

/**
 * 仿改的微信签名工具类
 *
 * @author Administrator
 */
public class WxPaySignKit {


    public static String hmacSha256(String data, String key) {
        return CommUtils.hmacSha256(data, key);
    }

    public static String md5(String data) {
        return CommUtils.md5(data);
    }



    /**
     * 支付异步通知时校验 sign
     *
     * @param params     参数
     * @param partnerKey 支付密钥
     * @return {boolean}
     */
    public static boolean verifyNotify(Map<String, Object> params, String partnerKey) {
        String sign = (String) params.get(ConstStr.FIELD_SIGN);
        SignUtils.SignType sType = SignUtils.SignType.MD5;
        if (params.containsKey(ConstStr.FIELD_SIGN_TYPE)) {
            sType = SignUtils.SignType.fromString((String) params.get(ConstStr.FIELD_SIGN_TYPE));
        }
        String localSign = createSign(params, partnerKey, sType);
        return sign.equals(localSign);
    }

    /**
     * 支付异步通知时校验 sign
     *
     * @param params     参数
     * @param partnerKey 支付密钥
     * @param signType   {@link SignUtils.SignType}
     * @return {@link Boolean} 验证签名结果
     */
    public static boolean verifyNotify(Map<String, Object> params, String partnerKey, SignUtils.SignType signType) {
        String sign = (String) params.get(ConstStr.FIELD_SIGN);
        String localSign = createSign(params, partnerKey, signType);
        return sign.equals(localSign);
    }

    /**
     * 生成签名
     *
     * @param params     需要签名的参数
     * @param partnerKey 密钥
     * @param signType   签名类型
     * @return 签名后的数据
     */
    public static String createSign(Map<String, Object> params, String partnerKey, SignUtils.SignType signType) {
        if (signType == null) {
            signType = SignUtils.SignType.MD5;
        }
        // 生成签名前先去除sign
        params.remove(ConstStr.FIELD_SIGN);
        String tempStr = CommUtils.createLinkString(params);
        String stringSignTemp = tempStr + "&key=" + partnerKey;
        if (signType == SignUtils.SignType.MD5) {
            return md5(stringSignTemp).toUpperCase();
        } else {
            return hmacSha256(stringSignTemp, partnerKey).toUpperCase();
        }
    }


    /**
     * 构建签名
     *
     * @param params     需要签名的参数
     * @param partnerKey 密钥
     * @param signType   签名类型
     * @return 签名后的 Map
     */
    public static Map<String, Object> buildSign(Map<String, Object> params, String partnerKey, SignUtils.SignType signType) {
        return buildSign(params, partnerKey, signType, true);
    }

    /**
     * 构建签名
     *
     * @param params       需要签名的参数
     * @param partnerKey   密钥
     * @param signType     签名类型
     * @param haveSignType 签名是否包含 sign_type 字段
     * @return 签名后的 Map
     */
    public static Map<String, Object> buildSign(Map<String, Object> params, String partnerKey, SignUtils.SignType signType, boolean haveSignType) {
        if (haveSignType) {
            params.put(ConstStr.FIELD_SIGN_TYPE, signType.getType());
        }
        String sign = createSign(params, partnerKey, signType);
        params.put(ConstStr.FIELD_SIGN, sign);
        return params;
    }

}
